package org.yelongframework.model.support.mybatis.sql.fragment.condition;

import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.ArrayUtils;
import org.yelongframework.model.support.mybatis.sql.MybatisBoundSql;
import org.yelongframework.model.support.mybatis.sql.MybatisParamMap;
import org.yelongframework.model.support.mybatis.sql.fragment.MybatisSqlFragmentException;
import org.yelongframework.sql.bound.SqlBound;
import org.yelongframework.sql.fragment.condition.ConditionSqlFragment;
import org.yelongframework.sql.fragment.condition.combination.CombinationConditionSqlFragment;
import org.yelongframework.sql.fragment.condition.combination.CombinationConditionSqlFragmentAttribute;
import org.yelongframework.sql.fragment.condition.combination.DefaultCombinationConditionSqlFragment;

/**
 * mybatis组合条件SQL片段默认实现
 * 
 * @since 1.0.0
 */
public class DefaultMybatisCombinationConditionSqlFragment extends DefaultCombinationConditionSqlFragment
		implements MybatisCombinationConditionSqlFragment {

	private String mybatisParamAlias;

	@Override
	public MybatisBoundSql getMybatisBoundSql() {
		MybatisParamMap mybatisParamMap = new MybatisParamMap("MYBATISPARAM");
		List<CombinationConditionSqlFragmentAttribute> combinationConditionSqlFragmentAttributes = getAttributes();
		for (CombinationConditionSqlFragmentAttribute combinationConditionSqlFragmentAttribute : combinationConditionSqlFragmentAttributes) {
			ConditionSqlFragment conditionSqlFragment = combinationConditionSqlFragmentAttribute
					.getConditionSqlFragment();
			// 如果为mybatisSQL则添加其参数映射
			if (conditionSqlFragment instanceof CombinationConditionSqlFragment) {
				if (conditionSqlFragment instanceof MybatisCombinationConditionSqlFragment) {
					MybatisCombinationConditionSqlFragment mybatisCombinationConditionSqlFragment = (MybatisCombinationConditionSqlFragment) conditionSqlFragment;
					mybatisCombinationConditionSqlFragment.setParamAlias(mybatisParamAlias);
					mybatisParamMap.putMybatisParamMap(
							mybatisCombinationConditionSqlFragment.getMybatisBoundSql().getMybatisParamMap());
				} else {
					throw new MybatisSqlFragmentException(
							"mybatis组合条件中添加组合条件必须为mybatis的组合条件而不应该为其他类型的组合条件，这可能导致解析为mybatis sql时错误。");
				}
			} else {
				Object[] params = conditionSqlFragment.getSqlBound(null).getParams();
				if (ArrayUtils.isNotEmpty(params)) {
					for (Object value : params) {
						mybatisParamMap.addParamMap(value);
					}
				}
			}
		}
		SqlBound boundSql = getSqlBound(null);
		// 修改生成的占位符？为mybatis占位符
		StringBuilder conditionSqlFragment = new StringBuilder(boundSql.getSql());
		Set<String> mybatisParamPlaceholderSet = mybatisParamMap.getPlaceholderParamMap().keySet();
		for (String paramPlaceholder : mybatisParamPlaceholderSet) {
			int index = conditionSqlFragment.indexOf("?");
			conditionSqlFragment.replace(index, index + 1, paramPlaceholder);
		}
		return new MybatisBoundSql(conditionSqlFragment.toString(), mybatisParamMap);
	}

	@Override
	public void setParamAlias(String paramAlias) {
		this.mybatisParamAlias = paramAlias;
	}

	@Override
	public String getParamAlias() {
		return mybatisParamAlias;
	}

}
